package com.mayfool.task.service;

import com.mayfool.task.bo.RemoteBO;
import com.mayfool.task.dao.ProjectDao;
import com.mayfool.task.dao.ProjectRepositoryRelDao;
import com.mayfool.task.dao.RepositoryDao;
import com.mayfool.task.entity.Project;
import com.mayfool.task.entity.ProjectRepositoryRel;
import com.mayfool.task.entity.Repository;
import com.mayfool.task.enums.RepoTypeEnum;
import com.mayfool.task.utils.FileUtil;
import com.mayfool.task.vo.repository.ScanRepositoryReqVO;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.List;

/**
 * @author zhou.xu 2024/8/27 18:21
 */
@Service
@RequiredArgsConstructor
public class RepositoryService {

    private final ProjectDao projectDao;
    private final RepositoryDao repositoryDao;
    private final ProjectRepositoryRelDao projectRepositoryRelDao;
    private final List<CvsService> cvsServices;

    public Repository save(Repository repository) {
        return repositoryDao.save(repository);
    }

    public void delete(Long id) {
        repositoryDao.deleteById(id);
    }

    public Repository get(Long id) {
        return repositoryDao.findById(id).orElse(null);
    }

    public List<Repository> list() {
        return repositoryDao.findAll();
    }

    @Transactional(rollbackOn = Exception.class)
    public void scan(ScanRepositoryReqVO reqVO) {
        CvsService cvsService = getCvsService(reqVO.getCvsType());
        List<File> dirs = FileUtil.listDirs(new File(reqVO.getLocation()), "." + reqVO.getCvsType(), reqVO.getMaxDepth());
        dirs.forEach(dir -> saveProjectAndRepository(reqVO, dir, cvsService));
    }

    private void saveProjectAndRepository(ScanRepositoryReqVO reqVO, File dir, CvsService cvsService) {
        File parentFile = dir.getParentFile();
        Project project = new Project();
        project.setName(parentFile.getName());
        project.setLocation(parentFile.getAbsolutePath());
        project = projectDao.save(project);

        List<RemoteBO> remoteBOS = cvsService.listRemote(dir.getAbsolutePath());
        for (RemoteBO remoteBO : remoteBOS) {
            Repository repository = new Repository();
            repository.setLocation(remoteBO.getRemoteUrl());
            repository.setRepoType(RepoTypeEnum.REMOTE.getCode());
            repository.setName(parentFile.getName());
            repository.setCvsType(reqVO.getCvsType());
            repository = repositoryDao.save(repository);

            ProjectRepositoryRel relation = new ProjectRepositoryRel();
            relation.setProjectId(project.getId());
            relation.setRepositoryId(repository.getId());
            relation.setRemoteName(remoteBO.getRemoteName());
            projectRepositoryRelDao.save(relation);
        }
    }

    private CvsService getCvsService(String cvsType) {
        return cvsServices.stream().filter(cvsService -> cvsService.getCvsType().getType().equals(cvsType)).findFirst().orElse(null);
    }
}
